using System;
using System.IO;					// Zur Arbeit mit Datei
using System.Collections.Generic;	// Grundlegende Datenstrukturen

namespace Graph
{
	public class DirectGraph : UndirectGraph
	{
        Dictionary<int, Dictionary<int, List<Kante>>> eOut = new Dictionary<int, Dictionary<int, List<Kante>>>();

        public DirectGraph()
            : base()
        {
            v = new Dictionary<int, Knoten>();
            e = new Dictionary<int, Dictionary<int, List<Kante>>>();
        }

        public int[] loadFlowGraph(string Path)
        {
            TextReader tr = File.OpenText(Path);
            string line;

            // n und m lesen
            line = tr.ReadLine();
            int n = int.Parse(line.Split(' ')[1]);
            int m = int.Parse(line.Split(' ')[3]);

            for (int i = 0; i < n; i++)
            {
                FlowKnoten knoten = new FlowKnoten(i);
                neuerKnoten(knoten);
            }

            // s unt t lesen
            line = tr.ReadLine();
            int s = int.Parse(line.Split(' ')[1]);
            line = tr.ReadLine();
            int t = int.Parse(line.Split(' ')[1]);
            int[] st = new int[] { s, t };

            while ((line = tr.ReadLine()) != null)
            {
                string[] lineElements = line.Split(' ');
                FlowKante kante = new FlowKante(int.Parse(lineElements[1]), int.Parse(lineElements[2]), int.Parse(lineElements[3]));
                neueKante(kante, kante.Gewicht);
            }

            return st;
        }


        public override void neuerKnoten(int id)
        {
            Knoten Node = new Knoten(id);
            v.Add(id, Node);
            e.Add(id, new Dictionary<int, List<Kante>>());
            eOut.Add(id, new Dictionary<int, List<Kante>>());
        }

        public override void neuerKnoten(Knoten Node)
        {
            v.Add(Node.Id, Node);
            e.Add(Node.Id, new Dictionary<int, List<Kante>>());
            eOut.Add(Node.Id, new Dictionary<int, List<Kante>>());
        }

        public override void neueKante(int von, int nach, double gewicht)
        {
            if (von == nach)
                throw new Exception(String.Format("Es sollte eine Schlinge von {0} nach {1} eingefügt werden! Graph unterstützt dies nicht!", von, nach));
            Kante Edge = new Kante(von,nach,gewicht);
            if (eOut[von].ContainsKey(nach))
                eOut[von][nach].Add(Edge);
            else
                eOut[von].Add(nach, new List<Kante> { Edge });

            if (e[nach].ContainsKey(von))
                e[nach][von].Add(Edge);
            else
                e[nach].Add(von, new List<Kante> {Edge});
        }
        public override void neueKante(Kante kante, double gewicht)
        {
            if (kante.Von == kante.Nach)
                throw new Exception(String.Format("Es sollte eine Schlinge von {0} nach {1} eingefügt werden! Graph unterstützt dies nicht!", kante.Von, kante.Nach));
            if (eOut[kante.Von].ContainsKey(kante.Nach))
                eOut[kante.Von][kante.Nach].Add(kante);
            else
                eOut[kante.Von].Add(kante.Nach, new List<Kante> { kante });

            if (e[kante.Nach].ContainsKey(kante.Von))
                e[kante.Nach][kante.Von].Add(kante);
            else
                e[kante.Nach].Add(kante.Von, new List<Kante> { kante });
        }

        public Dictionary<int, Dictionary<int, List<Kante>>> EOut { get { return eOut; } }
        public Dictionary<int, Dictionary<int, List<Kante>>> EIn { get { return e; } }
	}
}
